package com.robot;

import com.game.majiang.config.LogManager;
import com.game.majiang.logic.LogicTable;
import com.game.majiang.vo.UserVo;
import com.game.server.db.SqlHelper;
import com.timing.RobotTask;
import org.luna.datastruct.set.RandomReadWriteSet;

import javax.sql.rowset.CachedRowSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import lombok.Getter;

public class RobotManager {

  private static RobotManager instance;

  @Getter
  private static RobotTask task;

  private static RandomReadWriteSet<Integer> waiting;

  // 获取单例
  public static RobotManager getInstance() {
    if(instance == null) {
      instance = new RobotManager();
      task = new RobotTask();
    }
    return instance;
  }

  private RobotManager() {
    waiting = obtainAllRobotsId();
  }

  // 创建机器人
  public RobotClient createRobot(LogicTable table) {
    if (waiting.isEmpty()) return null;
    Integer id = waiting.removeRandom(); // 随机从读写集读取一个机器人用户
    LogManager.getInstance().Log("创建机器人：" + id);
    RobotClient robot = new RobotClient();
    robot.create(table, id);
    return robot;
  }

  // 重新存储空闲机器人
  public void restockRobot(Integer id) {
    waiting.add(id);
  }

  public void addRobot(RobotClient robot) {
    task.addClient(robot);
  }

  // 获取所有的机器人用户
  public RandomReadWriteSet<Integer> obtainAllRobotsId() {
    RandomReadWriteSet<Integer> res = new RandomReadWriteSet<>();
    String cmdText = "SELECT `id` FROM `users` WHERE `is_robot` = 1";
    CachedRowSet rs = SqlHelper.getResultSet(cmdText);
    try {
      while (rs.next()) {
        res.add(rs.getInt(1));
      }
    } catch (SQLException e) {
      LogManager.getInstance().Error("SQL Error: \n\tSQL TEXT: " +
          cmdText + "\n\tERROR: " + String.join("\n", Arrays.toString(e.getStackTrace())));
    }
    return res;
  }

  public List<UserVo> obtainAllRobotsInfo() {
    List<UserVo> res = new ArrayList<>();
    for (Integer id: waiting) {
      UserVo userVo = new UserVo(id);
      res.add(userVo);
    }
    return res;
  }

  public long robotsCount() {
    return waiting.size();
  }

}
